package cn.buk.tms.dao;

import cn.buk.common.sc.CommonSearchCriteria;
import cn.buk.common.sc.Page;
import cn.buk.tms.entity.misc.DetrInfo;
import cn.buk.tms.entity.misc.FlightPriceCache;
import cn.buk.common.util.DateUtil;
import cn.buk.tms.entity.misc.FlightPriceCache_;
import jakarta.persistence.criteria.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;

import jakarta.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: yfdai
 * Date: 14-5-11
 * Time: 下午10:30
 * To change this template use File | Settings | File Templates.
 */
@Component
@Transactional
public class FlightPolicyDaoImpl extends AbstractDao implements FlightPolicyDao {

    private static final Logger logger = LogManager.getLogger(FlightPolicyDaoImpl.class);

    @Override
    public List<FlightPriceCache> getSubclassPrice(String dport, String aport, String airline) {
        return em.createQuery("select o from FlightPriceCache o " +
                        "where o.dport = :dport " +
                        "and o.aport = :aport " +
                        "and o.carrier = :carrier order by o.fdDate",
                FlightPriceCache.class)
                .setParameter("dport", dport)
                .setParameter("aport", aport)
                .setParameter("carrier", airline)
                .getResultList();
    }

    /**
     * 保存DETR的票号
     *
     * @param tickets
     * @return
     */
    @Override
    public int createDetrTickets(int enterpriseId, List<String> tickets) {
        int count = 0;


        for (String ticketNo : tickets) {
            DetrInfo detrInfo = new DetrInfo();
            detrInfo.setEnterpriseId(enterpriseId);
            detrInfo.setDetrDone("0");
            detrInfo.setTicketNo(ticketNo);
            detrInfo.setBalanceCode(ticketNo.substring(0, 3));
            detrInfo.setCreateDate(DateUtil.getCurDate());

            em.persist(detrInfo);
            count++;
        }


        return count;
    }

    @Override
    public int createFlightPriceCaches(List<FlightPriceCache> flightPriceCaches) {
        int count = 0;
        for(FlightPriceCache priceCache : flightPriceCaches) {
            try {
                em.persist(priceCache);
            } catch (Exception ex) {
                logger.error(ex.getMessage());
            }
            count++;
        }
        return count;
    }


    @Override
    public List<FlightPriceCache> searchFlightPriceCache(int enterpriseId, CommonSearchCriteria sc) {
        List<FlightPriceCache> results = null;

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<FlightPriceCache> cq = cb.createQuery(FlightPriceCache.class);
        Root<FlightPriceCache> root = cq.from(FlightPriceCache.class);

        Predicate where = cb.conjunction();

        if (sc.getCarrier().length() > 0) {
            where = cb.and(where, cb.equal(root.get(FlightPriceCache_.carrier), sc.getCarrier()));
        }
        if (sc.getDport().length() == 3) {
            where = cb.and(where, cb.equal(root.get(FlightPriceCache_.dport), sc.getDport()));
        }
        if (sc.getAport().length() == 3) {
            where = cb.and(where, cb.equal(root.get(FlightPriceCache_.aport), sc.getAport()));
        }
        if (sc.getSubClass().length() > 0) {
            where = cb.and(where, cb.equal(root.get(FlightPriceCache_.subclass), sc.getSubClass()));
        }

        cq.where(where);
        List<Order> orderByes = new ArrayList<>();
        orderByes.add(cb.asc(root.get("departurePort")));
        orderByes.add(cb.asc(root.get("arrivalPort")));
        orderByes.add(cb.asc(root.get("carrier")));
        orderByes.add(cb.desc(root.get("price")));

        cq.orderBy(orderByes);

        //计算根据条件查询得出的数据总数
        CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
        Root<FlightPriceCache> countRoot = countQuery.from(FlightPriceCache.class);

        Predicate where0 = cb.conjunction();
        //****
        if (sc.getCarrier().length() > 0) {
            where0 = cb.and(where0, cb.equal(countRoot.get(FlightPriceCache_.carrier), sc.getCarrier()));
        }
        if (sc.getDport().length() == 3) {
            where0 = cb.and(where0, cb.equal(countRoot.get(FlightPriceCache_.dport), sc.getDport()));
        }
        if (sc.getAport().length() == 3) {
            where0 = cb.and(where0, cb.equal(countRoot.get(FlightPriceCache_.aport), sc.getAport()));
        }
        if (sc.getSubClass().length() > 0) {
            where0 = cb.and(where0, cb.equal(countRoot.get(FlightPriceCache_.subclass), sc.getSubClass()));
        }


        countQuery.select(cb.count(countRoot)).where(where0);
        Long count = em.createQuery(countQuery).getSingleResult();

        int maxResults = count.intValue();
        if (maxResults > 0) {
            Page page = sc.getPage();
            page.setRowCount(maxResults);
            int i = (page.getPageNo() - 1) * page.getPageSize();

            if (i < 0) {
              i = 0;
            }

            results = em.createQuery(cq)
                    .setFirstResult(i)
                    .setMaxResults(page.getPageSize()).getResultList();
        }


        if (results == null) {
          results = new ArrayList<>();
        }

        return results;
    }

  @Override
  public List<FlightPriceCache> searchFlightPriceCache(String dport, String aport, String carrier) {
    return em.createQuery("select o from FlightPriceCache o " +
            "where o.dport = :dport " +
            "and o.aport = :aport " +
            "and o.carrier = :carrier order by o.id", FlightPriceCache.class)
            .setParameter("dport", dport)
            .setParameter("aport", aport)
            .setParameter("carrier", carrier)
            .getResultList();
  }


}
